package p03;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * 一个bean从创建到销毁，称为bean生命周期（销毁的场景用的不多）
 * bean的生命周期由bean后处理器完成
 *
 * @author Chen weishuai
 * @since 2025/7/18
 */
@Slf4j
@SpringBootApplication
public class BeanLifeCycleDemo {
    public static void main(String[] args) {
        /**
         * bean从创建到销毁，有主要四个节点：实例，依赖注入，初始化，销毁(在这些节点的前或后有扩展点)
         * 可以通过自定义bean后处理器的方式，给这四个结点的前后扩展方法
         * 有哪些场景需在这四个主要节点前后扩展方法呢？
         * bean后处理器(MyBeanPostProcessor)被放入容器中即可，会自动被运行(这是boot提供的能力)
         */
        ConfigurableApplicationContext context = SpringApplication.run(BeanLifeCycleDemo.class, args);
        TestBean bean = context.getBean(TestBean.class);
        log.info("bean信息: {}", bean);
        log.info("调用关闭容器方法");
        context.close();
        log.info("容器已关闭");
        /**
         * 总结：在实例化单例Bean的过程中，会在9个地方执行5个后处理器
         *    1.BeanPostProcessor -> 两个抽象方法表示初始化前后
         *    2.InstantiationAwareBeanPostProcessor ->  实例化前、实例化后、属性注入时
         *    3.SmartInstantiationAwareBeanPostProcessor -> 预测最终bean类型、确定构造方法、获取原初bean示例的引用
         *    4.MergedBeanDefinitionPostProcessor -> 进行一些自省操作，如一些检测，或在处理bean实例之前缓存一些相关的元数据
         *    5.DestructionAwareBeanPostProcessor -> 销毁前
         *  我们可以实现上诉接口重写抽象方法，并加入容器，就实现了自定义的bean后处理器
         *  本质是在bean生命周期的特定节点，会从容器中找到特定类型的bean，然后回调其方法
         */
    }

}
